package com.tezign.intelligence.mini.dam.aifamilyconsultant.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.RequestStatusEnum;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.ResponseBean;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.req.GenerateReportReq;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.ReportTypeEnum;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.controller.AdminController;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.entity.*;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.service.*;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant.IGNORE_SESSION_CONTENT;

@Component
@EnableScheduling
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping(Constant.APPLICATION_NAME + "/tasks")
public class ScheduledTasks {

	private final AdminController adminController;

	private final IFamilyService familyService;

	private final IReportService reportService;

	private final IUserSessionService userSessionService;

	private final ISessionService sessionService;


	// 每天早上9点执行的任务
	@Scheduled(cron = "0 0 9 * * ?")
	@GetMapping("/public/recordCountAlert")
	public void performRecordContAlertTaskAt9AM() {
		LocalDateTime now = LocalDateTime.now();
		log.info("performRecordContAlertTaskAt9AM at {} ", now);
		List<Family> focusedFamilies = familyService.lambdaQuery().eq(Family::getFocus, true).list();
		String type = ReportTypeEnum.DAY.getType();
		String startTime = getStartTime(type);
		String endTime = getEndTime(type);
		focusedFamilies.forEach(family -> {
			try {
				List<UserSession> sessions = userSessionService.lambdaQuery().eq(UserSession::getFamilyId, family.getId()).list();
				if (CollUtil.isEmpty(sessions)) {
					return;
				}
				List<Long> userSessionIds = sessions.stream().map(UserSession::getId).collect(Collectors.toList());
				List<Session> lastDaySessionList = sessionService.lambdaQuery().in(Session::getUserSessionId, userSessionIds).notIn(Session::getContent, IGNORE_SESSION_CONTENT).between(Session::getCreateTime, startTime, endTime).list();
				if (lastDaySessionList.size() > 30) {
					return;
				}

				List<Session> sessionList = sessions.stream().map(x -> {
					Session session = new Session();
					session.setUserSessionId(x.getId());
					session.setRole(ChatMessageRole.ASSISTANT.value());
					session.setContent("最近沟通数量有点少，记得活跃起来哦");
					return session;
				}).collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(sessionList)) {
					sessionService.saveBatch(sessionList);
				}
			} catch (Exception e) {
				log.error("关注家庭活跃数检查失败", e);
			}
		});
	}


	// 每天早上9点执行的任务
	@Scheduled(cron = "0 0 9 * * ?")
	@GetMapping("/public/day")
	public void performTaskAt9AM() {
		generateReport(ReportTypeEnum.DAY.getType());

	}

	// 每周一天的凌晨1点执行一次
	@Scheduled(cron = "0 0 1 ? * MON")
	@GetMapping("/public/week")
	public void performTaskAtWeek() {
		generateReport(ReportTypeEnum.WEEK.getType());
	}


	// 每月1号凌晨1点执行一次
	@GetMapping("/public/month")
	@Scheduled(cron = "0 0 1 1 * ?")
	public void performTaskAtMonthly() {
		generateReport(ReportTypeEnum.MONTH.getType());
	}


	private void generateReport(String type) {
		LocalDateTime now = LocalDateTime.now();
		log.info("performTask at {} 生成报告 time={} type={}", type, now, type);
		List<Family> typeFamilies = familyService.lambdaQuery().eq(Family::getReportType, type).list();
		typeFamilies.forEach(family -> {
			GenerateReportReq req = new GenerateReportReq();
			req.setFamilyId(family.getId());

			LocalDateTime startTime = LocalDateTime.now().minusMonths(1);
			req.setStartTime(convertToDate(startTime));
			req.setEndTime(convertToDate(now));
			log.info("req={}", req);
			try {
				List<UserSession> sessions = userSessionService.lambdaQuery().eq(UserSession::getFamilyId, family.getId()).list();
				if (CollUtil.isEmpty(sessions)) {
					return;
				}
				List<Long> userSessionIds = sessions.stream().map(UserSession::getId).collect(Collectors.toList());

				Report one = reportService.lambdaQuery().eq(Report::getFamilyId, family.getId()).orderByDesc(Report::getId).last("limit 1").one();
				int size = 2;
				if (one != null) {
					List<Session> lastDaySessionList = sessionService.lambdaQuery().in(Session::getUserSessionId, userSessionIds).notIn(Session::getContent, IGNORE_SESSION_CONTENT).between(Session::getCreateTime, one.getSessionStartTime(), one.getSessionEndTime()).list();
					// 上一次报告生成的session条数
					size = lastDaySessionList.size();
				}
				List<Session> lastDaySessionList = sessionService.lambdaQuery().in(Session::getUserSessionId, userSessionIds).notIn(Session::getContent, IGNORE_SESSION_CONTENT).between(Session::getCreateTime, one != null ? one.getSessionStartTime() : startTime, now).list();
				if (lastDaySessionList.size() - size < 10) {
					log.info("最近一天的聊天记录小于2 不生成报告");
					return;
				}

				ResponseBean<Boolean> responseBean = adminController.generateReport(req);
				if (!StrUtil.equals(responseBean.getCode(), RequestStatusEnum.SUCCESS.getCode())) {
					log.info("没有生成报告: {}", JSON.toJSONString(responseBean));
					return;
				}

				// 重点关注家庭才推送报告
				if (Boolean.TRUE.equals(family.getFocus())) {
					List<Session> sessionList = sessions.stream().map(x -> {
						Session session = new Session();
						session.setUserSessionId(x.getId());
						session.setRole(ChatMessageRole.ASSISTANT.value());
						session.setContent("报告已生成，请查看报告信息");
						return session;
					}).collect(Collectors.toList());
					if (CollectionUtils.isNotEmpty(sessionList)) {
						sessionService.saveBatch(sessionList);
					}
				}
			} catch (Exception e) {
				log.error("every {} 分析报告生成失败", type, e);
				Report report = new Report();
				report.setFamilyId(family.getId());
				report.setSessionCount(0L);
				report.setReport(e.getMessage());
				reportService.save(report);
			}
		});
	}


	private static String getStartTime(String type) {
		LocalDateTime now = LocalDateTime.now();
		if ("day".equals(type)) {
			return convertToDate(now.toLocalDate().minusDays(1).atStartOfDay());
		}
		if ("week".equals(type)) {
			return convertToDate(now.toLocalDate().minusWeeks(1).atStartOfDay());
		}
		return convertToDate(now.toLocalDate().minusMonths(1).atStartOfDay());
	}

	private static String getEndTime(String type) {
		LocalDateTime now = LocalDateTime.now();
		if ("day".equals(type)) {
			return convertToDate(now.toLocalDate().minusDays(1).atTime(23, 59, 59));
		}
		if ("week".equals(type)) {
			return convertToDate(now.toLocalDate().minusDays(7).atTime(23, 59, 59));
		}
		return convertToDate(now.toLocalDate().minusMonths(1).atTime(23, 59, 59));
	}

	private static String convertToDate(LocalDateTime localDateTime) {
		// 使用系统默认的时区进行转换
		ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date.from(zdt.toInstant()));
	}
}
